# coding=utf8
from collections.abc import Iterable
from collections.abc import Iterator
import collections

def generator_test():
    i = 1
    while i < 3:
        yield i
        i += 1
        
# 调用返回的是一个generator, 本身是一个function,
print(generator_test())
print(generator_test)
# print(isinstance(generator_test(), Iterator))
# print(isinstance(generator_test(), Iterable))

# 遇到yield则返回,保存运行到的位置, 下次调用__next__()从本处开始
# it = generator_test()
# while True:
#     try:
#         print(it.__next__(), end=' ')
#     except StopIteration:
#         break

# 可以用for循环迭代
# for item in generator_test():
#     print(item, end=' ')

# 生成器(generator)表达式
# (expr for iter_var in iterable if cond_expr)
# gen = (x for x in range(100))
# for item in gen:
#     print(item, end=' ')

# 用生成器实现斐波那切数列
# def fib(n):
#     a, b = 0, 1
#     while b <= n:
#         yield b
#         a, b = b, a + b
#
#
# for item in fib(1000):
#     print(item, end=' ')

# 生成器send函数
# def generate_test2():
#     print('first in!')
#     while True:
#         n = yield 'from n = yield'
#         if n % 2 == 1:
#             yield 'odd'
#         else:
#             yield 'even'


# 第一次__next__()停在 n = yield
# 第二次__next__()raise TypeError
# gen = generate_test2()
# print(gen.__next__())
# print(gen.__next__())

# 不能在generator刚运行时就传入非None的值
# gen = generate_test2()
# gen.send(100)

# 刚运行时传入一个None却是可以的
# gen = generate_test2()
# gen.send(None)

# generator是不能被调用的
# gen = generate_test2()
# gen()

# gen = generate_test2()
# print(gen.__next__())   # n = None 第一个yield 返回 'from n = yield'
# print(gen.send(9))      # n = 9    第二个yield 返回 'odd'
# print(gen.send(10))     # n = 10   第一个yield 返回 'from n = yield'
# print(gen.send(10))     # n = 10   第三个yield 返回 'even'


# gen.__next__() 与 gen.send(None) 好像是等效的
# gen = generate_test2()
# print(gen.send(None))   # n = None 第一个yield 返回 'from n = yield'
# print(gen.send(9))      # n = 9    第二个yield 返回 'odd'
# print(gen.send(None))   # n = None 第一个yield 返回 'from n = yield'
# print(gen.send(10))     # n = 10   第三个yield 返回 'even'

# 记数器的例子
# def counter(start_at=0):
#     count = start_at
#     while True:
#         val = (yield count)
#         if val is not None:
#             count = val
#         else:
#             count += 1
#
#
# n = counter(5)
# print(n.__next__())
# print(n.__next__())
# print(n.send(0))
# print(n.__next__())
# print(n.__next__())

# 生成器可以通过close关闭
# def generator_test3():
#     while True:
#         yield 'ok'
#
#
# gen = generator_test3()
# print(gen.__next__())
# gen.close()
# try:
#     print(gen.__next__())
# except StopIteration:
#     print('\'generator\' raised StopIteration Error')


